package com.favccxx.search.domain.calcite;

import com.favccxx.search.domain.calcite.connection.CalciteConnectionService;
import com.favccxx.search.infrastructure.exception.AppException;
import com.favccxx.search.infrastructure.exception.ExceptionCode;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.calcite.jdbc.CalciteConnection;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.*;
import java.util.Arrays;
import java.util.List;

/**
 * @author favccxx
 */
@Slf4j
@Service
public class CalciteService {

    @Autowired
    CalciteModelService calciteModelService;
    @Autowired
    CalciteConnectionService calciteConnectionService;


    public String executeSql(String sql) throws ClassNotFoundException, SQLException {
        JSONArray jsonArray = new JSONArray();

        String queryResult = "";
        if (StringUtils.isBlank(sql)) {
            throw new AppException(ExceptionCode.Search.SEARCH_SQL_EMPTY);
        }


        try (
                Connection connection = calciteConnectionService.getConnection(sql);
                CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class);
        ) {
            Statement st = calciteConnection.createStatement();
            ResultSet rs = st.executeQuery(sql);
            ResultSetMetaData metadata = rs.getMetaData();
            int columnCount = metadata.getColumnCount();
            while (rs.next()) {
                JSONObject jsonObject = new JSONObject();
                for (int i = 1; i <= columnCount; i++) {
                    String columnName = metadata.getColumnLabel(i);
                    Object value = rs.getObject(columnName);
                    if (value instanceof byte[]) {
                        value = new String(rs.getBytes(i));
                    }
                    jsonObject.put(columnName, value);
                }
                jsonArray.put(jsonObject);
            }
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
            throw new AppException(ExceptionCode.Calcite.CONNECTION_FAILED, e);
        }
        return jsonArray.toString();
    }

}
